#pragma once

#include "kwdb/client.h"
#include "kwdb/point.h"
#include "kwdb/status.h"
#include <grpcpp/grpcpp.h>
#include <memory>
#include <vector>
#include <atomic>
#include <thread>
#include <mutex>

namespace kwdb {

// Forward declarations
namespace ingest { namespace v1 {
    class IngestService;
    class WriteRequest;
    class WriteResponse;
}}

/**
 * High-performance streaming client for batch writes
 * Uses gRPC client-side streaming for optimal throughput
 */
class StreamClient {
public:
    /**
     * Create a streaming client
     * @param config Configuration including endpoint and timeout
     */
    explicit StreamClient(const IngestConfig& config);
    ~StreamClient();

    /**
     * Start a new streaming session
     * Must be called before writing any data
     */
    Status StartStream();

    /**
     * Write a batch of points to the stream
     * Points are buffered and sent efficiently
     * @param points Vector of points to write
     */
    Status WriteBatch(const std::vector<Point>& points);

    /**
     * Write a single point to the stream
     * @param point Point to write
     */
    Status WritePoint(const Point& point);

    /**
     * Flush any buffered data immediately
     * Normally data is flushed automatically at optimal intervals
     */
    Status Flush();

    /**
     * Close the stream and get final response
     * Must be called to complete the stream
     * @return Final status with total rows written
     */
    Status Finish();

    /**
     * Check if stream is currently active
     */
    bool IsActive() const { return stream_active_.load(); }

    /**
     * Get total points written so far
     */
    uint64_t GetTotalWritten() const { return total_written_.load(); }

    // Columnar batch support (for maximum performance)
    Status WriteColumnar(const std::string& measurement,
                        const std::vector<int64_t>& timestamps,
                        const std::map<std::string, std::vector<std::string>>& tags,
                        const std::map<std::string, std::vector<double>>& fields);

private:
    class StreamClientImpl;
    std::unique_ptr<StreamClientImpl> impl_;

    std::atomic<bool> stream_active_{false};
    std::atomic<uint64_t> total_written_{0};

    // Configuration
    IngestConfig config_;
    size_t batch_size_threshold_ = 1000;
    int flush_interval_ms_ = 100;
};

} // namespace kwdb